home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 3 of 3 / CHAPTE17 / MIXER1.C < prev    next >
C/C++ Source or Header  |  1996-04-29  |  15KB  |  489 lines

  1.  
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "mixer1.h"
  5.  
  6. #if defined (WIN32)
  7.     #define IS_WIN32 TRUE
  8. #else
  9.     #define IS_WIN32 FALSE
  10. #endif
  11.  
  12. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  13. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  14. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  15.  
  16. HINSTANCE hInst;   // current instance
  17.  
  18. LPCTSTR lpszAppName = "MyApp";
  19. LPCTSTR lpszTitle   = "mixerGetDevCaps()"; 
  20.  
  21. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  22.  
  23.  
  24. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  25.                       LPTSTR lpCmdLine, int nCmdShow)
  26. {
  27.    MSG      msg;
  28.    HWND     hWnd; 
  29.    WNDCLASS wc;
  30.  
  31.    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  32.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  33.    wc.cbClsExtra    = 0;                      
  34.    wc.cbWndExtra    = 0;                      
  35.    wc.hInstance     = hInstance;              
  36.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  37.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  38.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  39.    wc.lpszMenuName  = lpszAppName;              
  40.    wc.lpszClassName = lpszAppName;              
  41.  
  42.    if ( IS_WIN95 )
  43.    {
  44.       if ( !RegisterWin95( &wc ) )
  45.          return( FALSE );
  46.    }
  47.    else if ( !RegisterClass( &wc ) )
  48.       return( FALSE );
  49.  
  50.    hInst = hInstance; 
  51.  
  52.    hWnd = CreateWindow( lpszAppName, 
  53.                         lpszTitle,    
  54.                         WS_OVERLAPPEDWINDOW, 
  55.                         CW_USEDEFAULT, 0, 
  56.                         CW_USEDEFAULT, 0,  
  57.                         NULL,              
  58.                         NULL,              
  59.                         hInstance,         
  60.                         NULL               
  61.                       );
  62.  
  63.    if ( !hWnd ) 
  64.       return( FALSE );
  65.  
  66.    ShowWindow( hWnd, nCmdShow ); 
  67.    UpdateWindow( hWnd );         
  68.  
  69.    while( GetMessage( &msg, NULL, 0, 0) )   
  70.    {
  71.       TranslateMessage( &msg ); 
  72.       DispatchMessage( &msg );  
  73.    }
  74.  
  75.    return( msg.wParam ); 
  76. }
  77.  
  78.  
  79. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  80. {
  81.     WNDCLASSEX wcex;
  82.  
  83.    wcex.style         = lpwc->style;
  84.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  85.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  86.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  87.    wcex.hInstance     = lpwc->hInstance;
  88.    wcex.hIcon         = lpwc->hIcon;
  89.    wcex.hCursor       = lpwc->hCursor;
  90.    wcex.hbrBackground = lpwc->hbrBackground;
  91.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  92.    wcex.lpszClassName = lpwc->lpszClassName;
  93.  
  94.    // Added elements for Windows 95.
  95.    //...............................
  96.    wcex.cbSize = sizeof(WNDCLASSEX);
  97.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  98.                             IMAGE_ICON, 16, 16,
  99.                             LR_DEFAULTCOLOR );
  100.             
  101.    return RegisterClassEx( &wcex );
  102. }
  103.  
  104. #define MSG_LEN          1024
  105. #define LB_TABSTOPS         6
  106. #define MAIN_LB           101
  107.  
  108. // global variables
  109. //.................
  110.  
  111. char       msg[MSG_LEN+1];
  112.  
  113. HWND       hListBox = NULL;
  114. INT        nTabStops[LB_TABSTOPS] = {50, 125, 210, 250, 300, 320};
  115. MMRESULT   rc;
  116.  
  117. MIXERCAPS  mxcaps;
  118. UINT       nDevId = 0;
  119. HMIXER     hmx    = NULL;
  120.  
  121.  
  122. VOID DisplayMixerLines(HWND hWnd);
  123. VOID GetComponentName(LPMIXERLINE pmxl, LPSTR lpszComponent);
  124.  
  125.  
  126. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  127. {
  128.    switch( uMsg )
  129.    {
  130.       case WM_CREATE :
  131.               // Create ListBox
  132.               //...............
  133.  
  134.               hListBox = CreateWindow( "LISTBOX", "",    
  135.                                        WS_CHILD | LBS_NOTIFY | 
  136.                                        WS_VSCROLL | WS_BORDER | 
  137.                                        WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
  138.                                        LBS_USETABSTOPS, 
  139.                                        0, 0, 
  140.                                        0, 0,  
  141.                                        hWnd,              
  142.                                        (HMENU)MAIN_LB,              
  143.                                        hInst,         
  144.                                        NULL );
  145.  
  146.               SendMessage(hListBox, LB_SETTABSTOPS, LB_TABSTOPS, (LPARAM)(LPINT)nTabStops);
  147.               break;
  148.  
  149.       case WM_SIZE :
  150.               MoveWindow( hListBox, 0, 0, 
  151.                           LOWORD( lParam ), 
  152.                           HIWORD( lParam ), TRUE );
  153.               break;
  154.  
  155.       case WM_COMMAND :
  156.               switch( LOWORD( wParam ) )
  157.               {
  158.                  case IDM_TEST:
  159.                         {
  160.                            SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  161.  
  162.                            if (mixerGetNumDevs() == 0)
  163.                            {
  164.                                MessageBox(hWnd, "No audio mixer devices found.", 
  165.                                           NULL, MB_OK);
  166.                                DestroyWindow(hWnd);  // shut down. app is not of any use.
  167.                                break;
  168.                            }
  169.  
  170.                            // list device capabilities for first installed 
  171.                            // mixer device
  172.                            //.............................................
  173.  
  174.                            nDevId = 0;
  175.  
  176.                            mixerGetDevCaps(nDevId, &mxcaps, sizeof(MIXERCAPS));
  177.                            sprintf(msg, "Device name: %s\t#Destinations: %ld", 
  178.                                    mxcaps.szPname, mxcaps.cDestinations);
  179.                            SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg);
  180.                            
  181.                            SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)"");
  182.  
  183.                            // open first device
  184.                            //..................
  185.  
  186.                            rc = mixerOpen(&hmx, nDevId, (DWORD)hWnd, (DWORD)NULL,
  187.                                           CALLBACK_WINDOW | MIXER_OBJECTF_MIXER);
  188.  
  189.                            if (rc != MMSYSERR_NOERROR)
  190.                            {
  191.                                MessageBox(hWnd, "Error opening mixer DevId = 0", 
  192.                                           NULL, MB_OK);
  193.                                DestroyWindow(hWnd);  // shut down
  194.                                break;
  195.                            }
  196.  
  197.                            // verify mixer ID
  198.                            //................
  199.  
  200.                            {
  201.                               UINT nDevIdChk;
  202.  
  203.                               rc = mixerGetID((HMIXEROBJ)hmx, &nDevIdChk, MIXER_OBJECTF_HMIXER);
  204.                            
  205.                               if (rc != MMSYSERR_NOERROR || nDevId != nDevIdChk)
  206.                               {
  207.                                   MessageBox(hWnd, "Error confirming mixer ID", 
  208.                                           NULL, MB_OK);
  209.                                   DestroyWindow(hWnd);  // shut down
  210.                                   break;
  211.                               }
  212.                            }
  213.  
  214.                            // display mixer lines
  215.                            //....................
  216.  
  217.                            DisplayMixerLines(hWnd);
  218.  
  219.                            // close mixer
  220.                            //............
  221.  
  222.                            mixerClose(hmx);
  223.                         }
  224.                         break;
  225.  
  226.                  case IDM_ABOUT :
  227.                         DialogBox( hInst, "AboutBox", hWnd, About );
  228.                         break;
  229.  
  230.                  case IDM_EXIT :
  231.                         DestroyWindow( hWnd );
  232.                         break;
  233.               }
  234.               break;
  235.  
  236.       
  237.  
  238.       case WM_DESTROY :
  239.               PostQuitMessage(0);
  240.               break;
  241.  
  242.       default :
  243.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  244.    }
  245.  
  246.    return( 0L );               
  247. }
  248.  
  249.  
  250. VOID DisplayMixerLines(HWND hWnd)
  251. {
  252.    LONG      nIndex;
  253.    UINT      uDest;
  254.    UINT      uConnect, uConnections;
  255.    MIXERLINE mxl;
  256.    char      lpszComponent[MSG_LEN];
  257.  
  258.    lstrcpy(msg, "Type\tComponent\tName\tLine ID\tFlags\tCtls\tConnections");
  259.    SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg);
  260.    SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)"");
  261.  
  262.    // loop and display all destination components
  263.    //............................................
  264.    
  265.    for (uDest = 0; uDest < mxcaps.cDestinations; uDest++)
  266.    {
  267.       mxl.cbStruct      = sizeof(mxl);
  268.       mxl.dwDestination = uDest;
  269.  
  270.       // get line info
  271.       //..............
  272.  
  273.       rc = mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_DESTINATION);
  274.    
  275.       if (rc != MMSYSERR_NOERROR)
  276.       {
  277.           sprintf(msg, "mixerGetLineInfo(dst=%u) failed.  rc=%u!",
  278.                     uDest, rc); 
  279.           MessageBox(hWnd, msg, NULL, MB_OK);
  280.           continue;
  281.       }
  282.  
  283.       // get line component name
  284.       //........................
  285.  
  286.       GetComponentName(&mxl, lpszComponent);
  287.  
  288.       sprintf(msg, "%s\t%-25s\t%-25s\t%.08lXh\t%.08lXh\t%lu\t%lu",
  289.               (MIXERLINE_LINEF_ACTIVE & mxl.fdwLine) ? "Dest Active" : "Dest Inactive",
  290.               (LPTSTR)lpszComponent,
  291.               (LPSTR)mxl.szName,
  292.               mxl.dwLineID,
  293.               mxl.fdwLine,
  294.               mxl.cControls,
  295.               mxl.cConnections
  296.              );
  297.  
  298.       nIndex = SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg);
  299.  
  300.       // loop and display all source components
  301.       // for above destination component
  302.       //.......................................
  303.       
  304.       uConnections = (UINT)mxl.cConnections;
  305.       
  306.       for (uConnect = 0; uConnect < uConnections; uConnect++)
  307.       {
  308.           mxl.cbStruct      = sizeof(mxl);
  309.           mxl.dwDestination = uDest;
  310.           mxl.dwSource      = uConnect;
  311.  
  312.           rc = mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_SOURCE);
  313.           
  314.           if (rc != MMSYSERR_NOERROR)
  315.           {
  316.               sprintf(msg, "mixerGetLineInfo(src=%u) failed.  rc=%u!",
  317.                       uConnect, rc); 
  318.               MessageBox(hWnd, msg, NULL, MB_OK);
  319.               continue;
  320.           }
  321.  
  322.           // get line component name
  323.           //........................
  324.  
  325.           GetComponentName(&mxl, lpszComponent);
  326.  
  327.           sprintf(msg, "%s\t%-25s\t%-25s\t%.08lXh\t%.08lXh\t%lu\t%lu",
  328.                   (MIXERLINE_LINEF_ACTIVE & mxl.fdwLine) ? "  Src Active" : "  Src Inactive",
  329.                   (LPTSTR)lpszComponent,
  330.                   (LPSTR)mxl.szName,
  331.                   mxl.dwLineID,
  332.                   mxl.fdwLine,
  333.                   mxl.cControls,
  334.                   mxl.cConnections
  335.                  );
  336.  
  337.           nIndex = SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg);
  338.           SendMessage(hListBox, LB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)mxl.dwLineID);
  339.       }
  340.       
  341.    }
  342. }
  343.  
  344. VOID GetComponentName(LPMIXERLINE pmxl, LPSTR lpszComponent)
  345. {
  346.     // translate component name
  347.     //.........................
  348.  
  349.     if (pmxl->fdwLine & MIXERLINE_LINEF_SOURCE)
  350.     {
  351.         // source components
  352.         //..................
  353.         
  354.         switch (pmxl->dwComponentType)
  355.         {
  356.            case MIXERLINE_COMPONENTTYPE_SRC_ANALOG:
  357.                    lstrcpy(lpszComponent, "Analog");
  358.                    break;
  359.            
  360.            case MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY:
  361.                    lstrcpy(lpszComponent, "Auxiliary");
  362.                    break;
  363.            
  364.            case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC:
  365.                    lstrcpy(lpszComponent, "Compact Disc");
  366.                    break;
  367.  
  368.            case MIXERLINE_COMPONENTTYPE_SRC_DIGITAL:
  369.                    lstrcpy(lpszComponent, "Digital");
  370.                    break;
  371.  
  372.            case MIXERLINE_COMPONENTTYPE_SRC_LINE:
  373.                    lstrcpy(lpszComponent, "Line Level");
  374.                    break;
  375.  
  376.            case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE:
  377.                    lstrcpy(lpszComponent, "Microphone");
  378.                    break;
  379.  
  380.            case MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER:
  381.                    lstrcpy(lpszComponent, "PC Speaker");
  382.                    break;
  383.            
  384.            case MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER:
  385.                    lstrcpy(lpszComponent, "Synthesizer");
  386.                    break;
  387.  
  388.            case MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE:
  389.                    lstrcpy(lpszComponent, "Telephone");
  390.                    break;
  391.  
  392.            case MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED:
  393.                    lstrcpy(lpszComponent, "Undefined");
  394.                    break;
  395.  
  396.            case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
  397.                    lstrcpy(lpszComponent, "Wave Out");
  398.                    break;
  399.  
  400.            default:
  401.                    lstrcpy(lpszComponent, "INVALID");
  402.                    break;
  403.         }
  404.     }
  405.     else
  406.     {
  407.         // destination components
  408.         //.......................
  409.  
  410.         switch (pmxl->dwComponentType)
  411.         {
  412.            case MIXERLINE_COMPONENTTYPE_DST_DIGITAL:
  413.                    lstrcpy(lpszComponent, "Digital");
  414.                    break;
  415.  
  416.            case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES:
  417.                    lstrcpy(lpszComponent, "Headphones");
  418.                    break;
  419.            
  420.            case MIXERLINE_COMPONENTTYPE_DST_LINE:
  421.                    lstrcpy(lpszComponent, "Line Level");
  422.                    break;
  423.  
  424.            case MIXERLINE_COMPONENTTYPE_DST_MONITOR:
  425.                    lstrcpy(lpszComponent, "Monitor");
  426.                    break;
  427.  
  428.            case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
  429.                    lstrcpy(lpszComponent, "Speakers");
  430.                    break;
  431.            
  432.            case MIXERLINE_COMPONENTTYPE_DST_TELEPHONE:
  433.                    lstrcpy(lpszComponent, "Telephone");
  434.                    break;
  435.  
  436.            case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED:
  437.                    lstrcpy(lpszComponent, "Undefined");
  438.                    break;
  439.            
  440.            case MIXERLINE_COMPONENTTYPE_DST_VOICEIN:
  441.                    lstrcpy(lpszComponent, "Voice Recognition");
  442.                    break;
  443.  
  444.            case MIXERLINE_COMPONENTTYPE_DST_WAVEIN:
  445.                    lstrcpy(lpszComponent, "Wave Input");
  446.                    break;
  447.            
  448.            default:
  449.                    lstrcpy(lpszComponent, "INVALID");
  450.                    break;
  451.         }
  452.     }
  453. }
  454.  
  455.  
  456. LRESULT CALLBACK About( HWND hDlg,           
  457.                         UINT message,        
  458.                         WPARAM wParam,       
  459.                         LPARAM lParam)
  460. {
  461.    switch (message) 
  462.    {
  463.        case WM_INITDIALOG: 
  464.                return (TRUE);
  465.  
  466.        case WM_COMMAND:                              
  467.                if (   LOWORD(wParam) == IDOK         
  468.                    || LOWORD(wParam) == IDCANCEL)    
  469.                {
  470.                        EndDialog(hDlg, TRUE);        
  471.                        return (TRUE);
  472.                }
  473.                break;
  474.    }
  475.  
  476.    return (FALSE); 
  477. }
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.